import sdk from '../index';
import { config } from '../../config';
import enemy from '../rpg/entity/enemy';
import { BattleCore } from '../rpg/BattleCore';
import { ComType } from '../tool/component';
import rpg_component from '../../component/rpg_component';
import player from '../rpg/entity/player';
import UserManager from './UserManager';

/**
 * 世界BOSS状态
 */
export enum WorldBossStatus {
    未出现 = 'none',
    出现 = 'spawned',
    战斗中 = 'fighting',
    已死亡 = 'dead',
    冷却中 = 'cooldown'
}

/**
 * 世界BOSS信息
 */
export interface WorldBossInfo {
    id: string;
    status: WorldBossStatus;
    spawnTime: number;
    deathTime: number;
    cooldownEndTime: number;
    participants: string[]; // 玩家ID列表
    lastBattleTime: number;
    nextBattleTime: number;
    bossEntity: enemy; // 使用现有的enemy类
}

/**
 * 世界BOSS管理器
 */
export class WorldBossManager {
    private static instance: WorldBossManager;
    private currentBoss: WorldBossInfo | null = null;
    private bossConfigs: any[] = [];
    private battleInterval: any = null;
    private spawnInterval: any = null;
    
    // 配置常量
    private readonly BATTLE_INTERVAL = 5000; // 30秒战斗间隔
    private readonly SPAWN_COOLDOWN = 10000; // 10秒生成冷却
    private readonly BOSS_CONFIG_KEY = 'enemy_世界boss';

    private constructor() {
        // 构造函数中不自动启动，等待手动初始化
    }

    public static getInstance(): WorldBossManager {
        if (!WorldBossManager.instance) {
            WorldBossManager.instance = new WorldBossManager();
        }
        return WorldBossManager.instance;
    }

    /**
     * 手动初始化世界BOSS系统
     */
    public init(): void {
        console.log('🌍 开始初始化世界BOSS系统...');
        this.loadBossConfigs();
        this.startBossCycle();
        console.log('🌍 世界BOSS系统初始化完成');
    }

    /**
     * 加载BOSS配置
     */
    private loadBossConfigs(): void {
        try {
            const configData = config.get(this.BOSS_CONFIG_KEY);
            if (configData) {
                this.bossConfigs = Array.from(configData.values());
                console.log(`🌍 已加载 ${this.bossConfigs.length} 个世界BOSS配置`);
            } else {
                console.error(`❌ 未找到世界BOSS配置: ${this.BOSS_CONFIG_KEY}`);
                this.bossConfigs = [];
            }
        } catch (error) {
            console.error('❌ 加载世界BOSS配置失败:', error);
            this.bossConfigs = [];
        }
    }

    /**
     * 启动BOSS循环
     */
    private startBossCycle(): void {
        // 立即生成第一个BOSS
        this.spawnNewBoss();
        
        // 设置战斗定时器
        this.battleInterval = setInterval(() => {
            this.executeBossBattle();
        }, this.BATTLE_INTERVAL);
        
        console.log('🌍 世界BOSS系统已启动');
    }

    /**
     * 生成新的世界BOSS
     */
    private spawnNewBoss(): void {
        if (this.bossConfigs.length === 0) {
            console.error('❌ 没有可用的BOSS配置');
            return;
        }

        // 随机选择一个BOSS配置
        const randomConfig = this.bossConfigs[Math.floor(Math.random() * this.bossConfigs.length)];
        const now = Date.now();
        
        // 创建BOSS实体，使用现有的enemy类
        const bossEntity = new enemy();
        bossEntity.randomConfig('世界boss');
        
        this.currentBoss = {
            id: `WB_${Date.now()}`,
            status: WorldBossStatus.出现,
            spawnTime: now,
            deathTime: 0,
            cooldownEndTime: 0,
            participants: [],
            lastBattleTime: now,
            nextBattleTime: now + this.BATTLE_INTERVAL,
            bossEntity: bossEntity
        };

        // 从BOSS实体获取信息
        const baseCom = bossEntity.getComponent(ComType.base) as any;
        const rpgCom = bossEntity.getComponent(ComType.rpg) as rpg_component;
        
        if (baseCom && rpgCom) {
            console.log(`🌍 世界BOSS已出现: ${baseCom.emoji}${baseCom.nickName} (HP: ${rpgCom.hp_now}/${(rpgCom as any).hp_max || rpgCom.hp_now})`);
        } else {
            console.log(`🌍 世界BOSS已出现: ${bossEntity.id}`);
        }
        
        this.broadcastBossSpawn();
    }



    /**
     * 玩家报名攻击BOSS
     */
    public registerForBattle(playerId: string): boolean {
        if (!this.currentBoss || this.currentBoss.status !== WorldBossStatus.出现) {
            return false;
        }

        if (this.currentBoss.participants.includes(playerId)) {
            return false;
        }

        this.currentBoss.participants.push(playerId);
        console.log(`⚔️ 玩家 ${playerId} 报名攻击世界BOSS`);
        return true;
    }

    /**
     * 执行BOSS战斗
     */
    private async executeBossBattle(): Promise<void> {
        if (!this.currentBoss || this.currentBoss.status !== WorldBossStatus.出现) {
            return;
        }

        if (this.currentBoss.participants.length === 0) {
            console.log('🌍 没有玩家报名攻击世界BOSS');
            return;
        }

        console.log(`⚔️ 开始世界BOSS战斗，参与者: ${this.currentBoss.participants.length}人`);
        
        this.currentBoss.status = WorldBossStatus.战斗中;
        this.currentBoss.lastBattleTime = Date.now();
        this.currentBoss.nextBattleTime = Date.now() + this.BATTLE_INTERVAL;

        try {
            const bossEntity = this.createBossEntity();
            const participants = await this.getParticipantPlayers();
            
            if (participants.length === 0) {
                console.log('🌍 没有有效的参与者，跳过战斗');
                this.currentBoss.status = WorldBossStatus.出现;
                return;
            }

            const battleResult = await this.createAndExecuteBattle(bossEntity, participants);
            this.handleBattleResult(battleResult);
            
        } catch (error) {
            console.error('❌ 世界BOSS战斗执行失败:', error);
            this.currentBoss.status = WorldBossStatus.出现;
        }
    }

    /**
     * 创建BOSS实体
     */
    private createBossEntity(): enemy {
        if (!this.currentBoss) {
            throw new Error('当前没有世界BOSS');
        }

        // 直接返回现有的BOSS实体
        return this.currentBoss.bossEntity;
    }

    /**
     * 获取参与者玩家
     */
    private async getParticipantPlayers(): Promise<player[]> {
        const players: player[] = [];
        
        console.log(`🔍 开始获取参与者玩家，参与者ID列表: ${this.currentBoss!.participants.join(', ')}`);
        
        for (const playerId of this.currentBoss!.participants) {
            try {
                console.log(`🔍 尝试获取玩家: ${playerId}`);
                const playerInstance = this.getPlayerById(playerId);
                if (playerInstance) {
                    console.log(`✅ 成功获取玩家: ${playerId}`);
                    players.push(playerInstance);
                } else {
                    console.log(`❌ 获取玩家失败: ${playerId} - 返回null`);
                }
            } catch (error) {
                console.error(`❌ 获取玩家异常: ${playerId}`, error);
            }
        }
        
        console.log(`📊 最终获取到的玩家数量: ${players.length}/${this.currentBoss!.participants.length}`);
        return players;
    }

    /**
     * 根据ID获取玩家实例
     */
    private getPlayerById(playerId: string): player | null {
        try {
            // 方案1: 从UserManager获取在线玩家（最优先）
            const onlinePlayer = UserManager.getOnlinePlayer(playerId);
            if (onlinePlayer) {
                console.log(`✅ 从UserManager成功获取在线玩家: ${playerId}`);
                return onlinePlayer;
            }
            
            // 方案2: 尝试从SDK获取玩家实例
            if (sdk && (sdk as any).player && (sdk as any).player.getById) {
                const sdkPlayer = (sdk as any).player.getById(playerId);
                if (sdkPlayer) {
                    console.log(`✅ 从SDK成功获取玩家: ${playerId}`);
                    return sdkPlayer;
                }
            }
            
            // 方案3: 尝试从全局玩家列表获取
            if ((global as any).playerList && (global as any).playerList.has(playerId)) {
                const globalPlayer = (global as any).playerList.get(playerId);
                if (globalPlayer) {
                    console.log(`✅ 从全局列表成功获取玩家: ${playerId}`);
                    return globalPlayer;
                }
            }
            
            // 方案4: 如果都没有，创建模拟玩家（仅用于测试）
            console.log(`⚠️ 无法获取真实玩家 ${playerId}，创建模拟玩家用于测试`);
            return this.createMockPlayer(playerId);
            
        } catch (error) {
            console.error(`❌ 获取玩家失败: ${playerId}`, error);
            return null;
        }
    }

    /**
     * 创建模拟玩家（用于测试）
     */
    private createMockPlayer(playerId: string): player {
        try {
            const mockPlayer = new player();
            mockPlayer.id = playerId;
            
            // 关键步骤：调用register()初始化所有组件
            mockPlayer.register();
            console.log(`🎭 模拟玩家 ${playerId} 组件初始化完成`);
            
            // 设置基本属性
            const rpgCom = mockPlayer.getComponent(ComType.rpg) as rpg_component;
            if (rpgCom) {
                rpgCom.hp_now = 100;
                (rpgCom as any).hp_max = 100;
                rpgCom.addSk({ skillId: 'A000', cooldown: 0, reName: '普通攻击' });
                console.log(`🎭 模拟玩家 ${playerId} RPG组件设置完成`);
            } else {
                console.log(`⚠️ 模拟玩家 ${playerId} RPG组件未找到`);
            }
            
            // 设置基础组件
            const baseCom = mockPlayer.getComponent(ComType.base) as any;
            if (baseCom) {
                baseCom.nickName = `模拟玩家_${playerId}`;
                baseCom.emoji = '🧙';
                console.log(`🎭 模拟玩家 ${playerId} 基础组件设置完成`);
            } else {
                console.log(`⚠️ 模拟玩家 ${playerId} 基础组件未找到`);
            }
            
            console.log(`🎭 成功创建模拟玩家: ${playerId}`);
            return mockPlayer;
            
        } catch (error) {
            console.error(`❌ 创建模拟玩家失败: ${playerId}`, error);
            // 如果创建失败，返回一个最基本的玩家对象
            const fallbackPlayer = new player();
            fallbackPlayer.id = playerId;
            // 尝试为fallback玩家也调用register
            try {
                fallbackPlayer.register();
            } catch (regError) {
                console.error(`❌ Fallback玩家register失败: ${playerId}`, regError);
            }
            return fallbackPlayer;
        }
    }

    /**
     * 创建并执行战斗
     */
    private async createAndExecuteBattle(bossEntity: enemy, players: player[]): Promise<any> {
        const battleCore = new BattleCore();
        
        battleCore.addUnit(bossEntity, false);
        
        players.forEach(player => {
            battleCore.addUnit(player, true);
        });

        battleCore.onKill((killLog: any, battleCore: any) => {
            console.log(`⚔️ 世界BOSS战斗击杀: ${killLog.masterId} 击杀了 ${killLog.targetId}`);
            
            if (killLog.targetId === bossEntity.id) {
                this.handleBossDeath();
            }
            
            console.log('🎯 击杀回调:', {
                killer: killLog.masterId,
                victim: killLog.targetId,
                battleArea: battleCore
            });
        });

        return new Promise((resolve) => {
            battleCore.start((result: any) => {
                console.log('⚔️ 世界BOSS战斗结束:', result);
                resolve(result);
            }, false);
        });
    }

    /**
     * 处理战斗结果
     */
    private handleBattleResult(battleResult: any): void {
        if (!this.currentBoss) return;

        // 检查BOSS是否死亡
        const rpgCom = this.currentBoss.bossEntity.getComponent(ComType.rpg) as rpg_component;
        if (rpgCom && rpgCom.isDie()) {
            this.handleBossDeath();
        } else {
            this.currentBoss.status = WorldBossStatus.出现;
            this.currentBoss.participants = [];
        }
    }

    /**
     * 处理BOSS死亡
     */
    private handleBossDeath(): void {
        if (!this.currentBoss) return;

        // 从BOSS实体获取信息
        const baseCom = this.currentBoss.bossEntity.getComponent(ComType.base) as any;
        const bossName = baseCom?.nickName || '未知BOSS';
        
        console.log(`💀 世界BOSS ${bossName} 已被击杀!`);
        
        this.currentBoss.status = WorldBossStatus.已死亡;
        this.currentBoss.deathTime = Date.now();

        this.broadcastBossDeath();
        this.startSpawnCooldown();
    }

    /**
     * 开始生成冷却
     */
    private startSpawnCooldown(): void {
        if (!this.currentBoss) return;

        this.currentBoss.status = WorldBossStatus.冷却中;
        this.currentBoss.cooldownEndTime = Date.now() + this.SPAWN_COOLDOWN;

        console.log(`⏳ 世界BOSS生成冷却开始，${this.SPAWN_COOLDOWN / 1000}秒后生成新BOSS`);

        this.spawnInterval = setTimeout(() => {
            this.spawnNewBoss();
        }, this.SPAWN_COOLDOWN);
    }

    /**
     * 广播BOSS出现消息
     */
    private broadcastBossSpawn(): void {
        if (!this.currentBoss) return;

        // 从BOSS实体获取信息
        const baseCom = this.currentBoss.bossEntity.getComponent(ComType.base) as any;
        const rpgCom = this.currentBoss.bossEntity.getComponent(ComType.rpg) as rpg_component;
        
        const bossName = baseCom?.nickName || '未知BOSS';
        const bossEmoji = baseCom?.emoji || '🌍';
        const currentHP = rpgCom?.hp_now || 0;
        const maxHP = (rpgCom as any)?.hp_max || currentHP;

        const message = `🌍 世界BOSS ${bossEmoji}${bossName} 已经出现！\n` +
                       `💀 HP: ${currentHP}/${maxHP}\n` +
                       `⚔️ 发送[攻击BOSS]参与战斗！\n` +
                       `⏰ 每5秒进行一次战斗`;

        console.log('📢 世界BOSS出现广播:', message);
    }

    /**
     * 广播BOSS死亡消息
     */
    private broadcastBossDeath(): void {
        if (!this.currentBoss) return;

        // 从BOSS实体获取信息
        const baseCom = this.currentBoss.bossEntity.getComponent(ComType.base) as any;
        const bossName = baseCom?.nickName || '未知BOSS';
        const bossEmoji = baseCom?.emoji || '🌍';

        const message = `💀 世界BOSS ${bossEmoji}${bossName} 已被击败！\n` +
                       `🎉 所有参与者将获得奖励！\n` +
                       `⏰ 10秒后将出现新的世界BOSS`;

        console.log('📢 世界BOSS死亡广播:', message);
    }

    /**
     * 获取当前世界BOSS信息
     */
    public getWorldBossInfo(): WorldBossInfo | null {
        return this.currentBoss;
    }

    /**
     * 检查是否可以攻击BOSS
     */
    public canAttackBoss(): boolean {
        return this.currentBoss !== null && 
               this.currentBoss.status === WorldBossStatus.出现;
    }

    /**
     * 获取下次战斗倒计时
     */
    public getNextBattleCountdown(): number {
        if (!this.currentBoss || this.currentBoss.status !== WorldBossStatus.出现) {
            return 0;
        }

        const now = Date.now();
        const remaining = Math.max(0, this.currentBoss.nextBattleTime - now);
        return Math.ceil(remaining / 1000);
    }

    /**
     * 获取BOSS状态描述
     */
    public getBossStatusDescription(): string {
        if (!this.currentBoss) {
            return '🌍 当前没有世界BOSS';
        }

        const boss = this.currentBoss;
        
        // 从BOSS实体获取信息
        const baseCom = boss.bossEntity.getComponent(ComType.base) as any;
        const rpgCom = boss.bossEntity.getComponent(ComType.rpg) as rpg_component;
        
        const bossName = baseCom?.nickName || '未知BOSS';
        const bossEmoji = baseCom?.emoji || '🌍';
        const currentHP = rpgCom?.hp_now || 0;
        const maxHP = (rpgCom as any)?.hp_max || currentHP;
        
        let description = `🌍 世界BOSS: ${bossEmoji}${bossName}\n`;

        switch (boss.status) {
            case WorldBossStatus.出现:
                const countdown = this.getNextBattleCountdown();
                description += `💀 HP: ${currentHP}/${maxHP}\n`;
                description += `⚔️ 参与者: ${boss.participants.length}人\n`;
                description += `⏰ 下次战斗: ${countdown}秒后`;
                break;
            case WorldBossStatus.战斗中:
                description += `⚔️ 战斗中...\n`;
                description += `💀 HP: ${currentHP}/${maxHP}`;
                break;
            case WorldBossStatus.已死亡:
                description += `💀 已被击败！\n`;
                description += `🎉 等待生成新BOSS...`;
                break;
            case WorldBossStatus.冷却中:
                const cooldownRemaining = Math.ceil((boss.cooldownEndTime - Date.now()) / 1000);
                description += `⏳ 生成冷却中...\n`;
                description += `⏰ ${cooldownRemaining}秒后生成新BOSS`;
                break;
        }

        return description;
    }

    /**
     * 清理资源
     */
    public destroy(): void {
        if (this.battleInterval) {
            clearInterval(this.battleInterval);
            this.battleInterval = null;
        }
        if (this.spawnInterval) {
            clearTimeout(this.spawnInterval);
            this.spawnInterval = null;
        }
    }
}

export default WorldBossManager.getInstance(); 